function [H, D] = calculatePreconditioner3D(n,precondInd,precision)
    filename=sprintf('filters%sH3Dfilter%dprecond%dprecision%s.dat',...
        filesep,n,mod(precondInd,2),precision);
    D = 0;
    if exist(filename,'file')
        H=load3DHFilter(filename,precision);
    else
        m=3*n+1;
        preconditioner=ones(m,n+1,n+1,precision);
        if precondInd
            for k=-3*n/2:3*n/2
                preconditioner(k+3*n/2+1,:,:)=(abs(k^2-k+1/3)+abs(k^2+k+1/3))/2;
            end
        end
        H=makeHFilter3D(n,preconditioner,precision);
        save3DHFilter(filename,n,mod(precondInd,2),precision,H);
    end
    if precondInd == 2
        filename=sprintf('preconditioners%sDiagonal3D%dprecision%s.dat',filesep,n,precision);
        if exist(filename,'file')
            fid=fopen(filename,'r');
            if strcmp(precision,'single')
                D=fread(fid,n^3,'real*4');
            elseif strcmp(precision,'double')
                D=fread(fid,n^3,'real*8');
            else
                error('precision must be single or double');
            end
            fclose(fid);
        else
            D=calculateDiagonalPreconditioner3D(H,n,precision); % and save
        end
    end
end